#include "EffectManagement.h"

EffectManagement::~EffectManagement()
{
    for (auto it = effects_list.begin(); it != effects_list.end();)
    {
        delete *it;
        it = effects_list.erase(it);
    }
}

Effect *EffectManagement::createEffect(ym::Json *data, Vector2 position, real facing, real aliveTime)
{
    if (data == nullptr)
    {
        return nullptr;
    }
    Effect *effect = new Effect();

    ym::Json *ani_josn = Data::getInstance()->getData(data->get("animation")->getString().c_str());
    ym::Json *ani_frames = ani_josn->get("frames");
    ym::Json::Array array = ani_frames->getArray();
    effect->aliveTime = aliveTime;
    if (aliveTime <= 0)
    {
        effect->aliveTime = data->get("alivetime")->getDouble();
    }
    else
    {
        effect->aliveTime = so_min(data->get("alivetime")->getDouble(), aliveTime);
    }
    if (data->hasKey("color"))
    {
        ym::Json::Array color = data->get("color")->getArray();
        effect->setColor({(unsigned char)color.at(0)->getInt(), (unsigned char)color.at(1)->getInt(), (unsigned char)color.at(2)->getInt(), (unsigned char)color.at(3)->getInt()});
    }
    ym::Json::Array renderSize = ani_josn->get("rendersize")->getArray();
    ym::Json::Array offset = ani_josn->get("offset")->getArray();
    IAnimation *ani = new IAnimation(Vector2(renderSize.at(0)->getInt(), renderSize.at(1)->getInt()), Vector2(offset.at(0)->getInt(), offset.at(1)->getInt()));
    Resource *resource = Resource::getInstance();
    for (auto it = array.begin(); it != array.end(); ++it)
    {
        ym::Json::Array frame = (*it)->getArray();
        ani->addFrame(resource->getImage(frame.at(0)->getString()), frame.at(1)->getDouble());
    }
    ani->start();
    effect->ani = ani;
    effect->setPosition(position);
    effect->facing = facing;
    effects_list.push_back(effect);

    return effect;
}

void EffectManagement::destroyEffect(Effect *effect)
{
    if (effect == nullptr)
    {
        return;
    }
    effect->exit();
}

const std::vector<Effect *> *EffectManagement::getEffects()
{
    return &effects_list;
}

void EffectManagement::update(real delta)
{
    for (auto it = effects_list.begin(); it != effects_list.end();)
    {
        Effect *effect = *it;
        if (effect->isExited())
        {
            it = effects_list.erase(it);
            delete effect;
        }
        else
        {
            if (effect->lifeTimer.getElapsedDoubleSeconds() >= effect->aliveTime)
            {
                effect->exit();
            }
            else
            {
                if (effect->ani != nullptr)
                {
                    effect->ani->update(delta);
                }
            }
            ++it;
        }
    }
}
